# TODO: 感知机模型笔记
# DATE: 2022/3/15
# AUTHOR: Cheng Ze WUST
import tensorflow as tf
import os
import numpy as np
# 感知机与门参数：(0.5,0.5,0.6)、(0.5,0.5,0.7)、(0.5,0.5,0.8)、(0.5,0.5,0.9)   --都1才1
# 感知机或门参数：(0.8,0.7.0.6)、(0.8,0.8,0.6)、(0.8,0.8,0.7)  --有1就1
# 感知机与非门参数：(-0.8,-0.7,-0.9)、(-0.5,-0.6,-0.7)、(-0.3,-0.4,-0.5) --与结果取反

# region Python实现门电路
and_params = {"w1": 0.5, "w2": 0.5, "theta": 0.6}
or_params = {"w1": 0.8, "w2": 0.7, "theta": 0.6}
and_not_params = {"w1": -0.8, "w2": -0.7, "theta": -0.9}
def preceptron(x1, x2, params):
    n = x1*params["w1"]+x2*params["w2"]
    theta = params["theta"]
    if n <= theta:
        return 0
    elif n > theta:
        return 1

print('与门电路感知机：x1=0,x2=0,y=', preceptron(0,0,and_params))
print('与门电路感知机：x1=1,x2=0,y=', preceptron(1,0,and_params))
print('与门电路感知机：x1=1,x2=1,y=', preceptron(1,1,and_params))
print('或门电路感知机：x1=0,x2=0,y=', preceptron(0,0,or_params))
print('或门电路感知机：x1=1,x2=0,y=', preceptron(1,0,or_params))
print('或门电路感知机：x1=1,x2=1,y=', preceptron(1,1,or_params))
print('与非门电路感知机：x1=0,x2=0,y=', preceptron(0,0,and_not_params))
print('与非门电路感知机：x1=1,x2=0,y=', preceptron(1,0,and_not_params))
print('与非门电路感知机：x1=1,x2=1,y=', preceptron(1,1,and_not_params))
# endregion

# region Tensorflow实现感知机
os.environ['TF_CPP_MIN_LOG_LEVEL']='3'  #设置日志级别
and_params={'w1':tf.Variable(0.5),'w2':tf.Variable(0.5),'theta':tf.Variable(0.6)}
or_params={'w1':tf.Variable(0.8),'w2':tf.Variable(0.7),'theta':tf.Variable(0.6)}
and_not_params={'w1':tf.Variable(-0.8),'w2':tf.Variable(-0.7),'theta':tf.Variable(-0.9)}
#感知机函数
def perceptronTF(x1,x2,params):
    w1=params['w1']
    w2=params['w2']
    theta=params['theta'].numpy()
    #print(theta)
    n = (x1 * w1 + x2 * w2).numpy()
    if n<=theta:
        return tf.constant(0)
    elif n>theta:
        return tf.constant(1)

x1=tf.Variable(1.0)
x2=tf.Variable(1.0)
y=perceptronTF(x1,x2,and_params)
print('与门感知机：x1=1,x2=1,y=',y.numpy())
x1=tf.Variable(1.0)
x2=tf.Variable(0.0)
y=perceptronTF(x1,x2,or_params)
print('或门感知机：x1=1,x2=0,y=',y.numpy())
x1=tf.Variable(1.0)
x2=tf.Variable(1.0)
y=perceptronTF(x1,x2,and_not_params)
print('与非门感知机：x1=1,x2=1,y=',y.numpy())
# endregion

# region 用偏置代替阈值
# y=0, b+w1x1+w2x2<=0
# y=1, b+w1x1+w2x2>0
x=np.array([0,1])
w=np.array([0.5,0.5])
b=-0.8
print(w*x)
print(np.sum(w*x)+b)
# endregion

# region 用Python和Tensorflow实现带偏置的感知机
# python
def and_perceptron(x1,x2):
    x=np.array([x1,x2])
    w=np.array([0.5,0.5])
    b=-0.8
    tmp=np.sum(w*x)+b
    if tmp<=0:
        return 0
    else:
        return 1
print('与门电路感知机：x1=1,x2=1,y=', and_perceptron(1,1))

#tensorflow
os.environ['TF_CPP_MIN_LOG_LEVEL']='3'
def and_perceptronTF(x1,x2):
    w1 = tf.constant(0.5)
    w2 = tf.constant(0.5)
    b = tf.constant(-0.8)
    tmp=(w1*x1+w2*x2+b).numpy()
    if tmp<=0:
        return tf.constant(0)
    else:
        return tf.constant(1)
def or_perceptronTF(x1,x2):
    w1 = tf.constant(0.8)
    w2 = tf.constant(0.7)
    b = tf.constant(-0.6)
    tmp=(w1*x1+w2*x2+b).numpy()
    if tmp<=0:
        return tf.constant(0)
    else:
        return tf.constant(1)
print('与门电路感知机：x1=1,x2=0,y=', and_perceptronTF(tf.constant(1.0),tf.constant(0.0)).numpy())
print('或门电路感知机：x1=1,x2=1,y=', or_perceptronTF(tf.constant(1.0),tf.constant(1.0)).numpy())
# endregion

# region 用多层感知机处理异或门 --不同就为1
def and_perceptron(x1,x2):
    n=x1*0.5+x2*0.5
    theta=0.6
    if n<=theta: return 0
    else: return 1
def or_perceptron(x1,x2):
    n=x1*0.8+x2*0.7
    theta=0.6
    if n<=theta: return 0
    else: return 1
def and_not_perceptron(x1,x2):
    n=x1*-0.8+x2*-0.7
    theta=-0.9
    if n<=theta: return 0
    else: return 1
#异或门感知机
def xor_perceptron(x1,x2):
    s1=and_not_perceptron(x1,x2)
    s2=or_perceptron(x1,x2)
    return and_perceptron(s1,s2)
print("异或门感知机：x1=0，x2=0，y=",xor_perceptron(0,0))
print("异或门感知机：x1=1，x2=0，y=",xor_perceptron(1,0))
print("异或门感知机：x1=1，x2=1，y=",xor_perceptron(1,1))

# endregion








